﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Text.RegularExpressions;

namespace MetMax
{
    public partial class OptionForm : Form
    {
        public Options _myOptions
        {
            get { return (Options)this.bs_options.DataSource; }
            set { this.bs_options.DataSource = value; }
        }

        public OptionForm()
        {
            InitializeComponent();
        }

        public OptionForm(Options o)
            : this()
        {
            this._myOptions = o;
            dgv_metaboliteMasses.DataSource = _myOptions.dataset.MetaboliteFragments;
        }

        private void btn_apply_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
        }

        private void btn_cancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        private void OptionForm_Shown(object sender, EventArgs e)
        {
            radioButton_version2.Checked = _myOptions.version_RetentionAnalysis;
            radioButton_version3.Checked = _myOptions.version_IsotopeConcentrator;
            radioButton_version4.Checked = _myOptions.version_LibrarySearch;

            propertyGrid1.SelectedObject = _myOptions;
        }

        private void btn_default_Wraps_Click(object sender, EventArgs e)
        {
            _myOptions.wrapArounds.Add(new WrapAround("#c10", 0));
            _myOptions.wrapArounds.Add(new WrapAround("#c12", 0));
            _myOptions.wrapArounds.Add(new WrapAround("#c15", 0));
            _myOptions.wrapArounds.Add(new WrapAround("#c18", 0));
            _myOptions.wrapArounds.Add(new WrapAround("#c19", 0));
            _myOptions.wrapArounds.Add(new WrapAround("#c28", 1));
            _myOptions.wrapArounds.Add(new WrapAround("#c32", 1));
            _myOptions.wrapArounds.Add(new WrapAround("#c36", 2));

            (dgv_wraparounds.DataSource as BindingSource).ResetBindings(false);
        }

        private void btn_export_Click(object sender, EventArgs e)
        {
            Stream myStream;
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*";
            saveFileDialog.FilterIndex = 0;
            saveFileDialog.RestoreDirectory = true;

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                if ((myStream = saveFileDialog.OpenFile()) != null)
                {
                    _myOptions.wrapArounds.WriteXml(myStream);
                    myStream.Close();
                    MessageBox.Show(string.Format("list saved into file '{0}'", saveFileDialog.FileName), "export", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show(string.Format("error opening file '{0}'", saveFileDialog.FileName), "export", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void btn_import_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*";
            openFileDialog.FilterIndex = 0;
            openFileDialog.RestoreDirectory = true;

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                Stream myStream;
                if ((myStream = File.Open(openFileDialog.FileName, FileMode.Open)) != null)
                {
                    _myOptions.wrapArounds.ReadXml(myStream);
                    (dgv_wraparounds.DataSource as BindingSource).ResetBindings(false);
                    myStream.Close();
                }

                MessageBox.Show(string.Format("{0} wrapArounds loaded from file '{1}'", _myOptions.wrapArounds.Count, openFileDialog.FileName), "import", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }


        private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if ((this._myOptions.Importer_version != Options.ImporterVersion.RetentionAnalysis) && (e.TabPage == tab_exportFact))
            {
                e.Cancel = true;
                MessageBox.Show("tab page only available for importer version 2!", "not available in this context", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
            else if ((this._myOptions.Importer_version != Options.ImporterVersion.IsotopeConcentrator) && (e.TabPage == tab_metaboliteMasses))
            {
                e.Cancel = true;
                MessageBox.Show("tab page only available for importer 'Isotope Concentrator'!", "not available in this context", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }

        private void btn_import_metaboliteMasses_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofdlg = new OpenFileDialog();
            if (ofdlg.ShowDialog() == DialogResult.OK)
            {
                TextReader textreader;
                try
                {
                    textreader = new StreamReader(new FileStream(ofdlg.FileName, FileMode.Open, FileAccess.Read), Encoding.Default);
                }
                catch (Exception e1)
                {
                    MessageBox.Show(string.Format("Error accessing file '{0}'\n{1}", ofdlg.FileName, e1.Message), string.Format("Error in {0}", e1.Source), MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }

                IEnumerable<string[]> rows = from splittedLine in LoadSingleSplittedLineFromFile(textreader, "\t")//.AsParallel()
                                             select splittedLine;

                //Parallel.ForEach<string[]>(rows, l =>
                foreach (string[] l in rows)
                {
                    if (l.Count() >= 7)
                    {
                        MetMaxDataSet.MetaboliteFragmentsRow s;
                        lock (_myOptions.dataset.MetaboliteFragments)
                        {
                            s = _myOptions.dataset.MetaboliteFragments.NewMetaboliteFragmentsRow();
                        }

                        try
                        {
                            s.name = Regex.Replace(l[0], "\"", string.Empty);
                            s.fragment_mass_min = short.Parse(l[1]);
                            s.fragment_mass_max = short.Parse(l[2]);
                            s.retention_index = float.Parse(l[3]);
                            s.position = Regex.Replace(l[4], "\"", string.Empty);
                            s.link = l[6];

                            lock (_myOptions.dataset.MetaboliteFragments)
                            {
                                _myOptions.dataset.MetaboliteFragments.AddMetaboliteFragmentsRow(s);
                            }
                        }
                        catch (FormatException ex)
                        {
                            MessageBox.Show(string.Format("{0}\r\n{1}", ex.Message, string.Join("|", l)), "FormatException");
                        }
                        catch (ConstraintException ex)
                        {
                            MessageBox.Show(ex.Message, "ConstraintException");
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                        }
                    }
                }

                textreader.Close();
            }

            dgv_metaboliteMasses.Refresh();
            return;
        }

        public IEnumerable<String[]> LoadSingleSplittedLineFromFile(TextReader textreader, String delimiter)
        {
            //lock (textreader)
            //{
            while (textreader.Peek() != -1)
            {
                yield return textreader.ReadLine().Split(delimiter.ToCharArray());
            }
            //}
            //yield break
        }

        private void dgv_wraparounds_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if (dgv_wraparounds.IsCurrentCellDirty)
            {
                DataGridViewCell cell = dgv_wraparounds[e.ColumnIndex, e.RowIndex];
                if (_myOptions.wrapArounds.Contains(e.FormattedValue.ToString()))
                {
                    cell.ErrorText = "Invalid Jata entered n ce1";
                    if (cell.Tag == null)
                    {
                        cell.Tag = cell.Style.Padding;
                        cell.Style.Padding = new Padding(0, 0, 18, 0);
                    }
                    e.Cancel = true;
                }
                else
                {
                    cell.ErrorText = string.Empty;
                }
            }
        }

        private void OptionForm_Load(object sender, EventArgs e)
        {

        }
    }
}
